package cn.sp.heartbeat;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.util.CharsetUtil;

public class NettyClient {

	private static final String HOST = "127.0.0.1";
	
	private static final int PORT = 9911;
	
	private ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
	
	EventLoopGroup group = new NioEventLoopGroup();
	
	
	  private void connect(String host,int port){
	        try {
	            Bootstrap b = new Bootstrap();
	            b.group(group)
	                    .channel(NioSocketChannel.class)
	                    .option(ChannelOption.TCP_NODELAY,true)
	                    .option(ChannelOption.SO_KEEPALIVE,true)
	                    .remoteAddress(new InetSocketAddress(host,port))
	                    .handler(new ChannelInitializer<SocketChannel>() {
	                        @Override
	                        protected void initChannel(SocketChannel ch) throws Exception {
	                            ByteBuf delimiter = Unpooled.copiedBuffer("$_", CharsetUtil.UTF_8);
	                            ch.pipeline()
	                                    .addLast(new DelimiterBasedFrameDecoder(1024,delimiter))
	                                    .addLast(new StringDecoder())
	                                    // 当一定周期内(默认50s)没有收到对方任何消息时，需要主动关闭链接
	                                    .addLast("readTimeOutHandler",new ReadTimeoutHandler(50))
	                                    .addLast("heartBeatHandler",new HeartBeatReqHandler());
	                        }
	                    });
	            // 发起异步连接操作
	            ChannelFuture future = b.connect().sync();
	            future.channel().closeFuture().sync();
	        }catch (Exception e){
	            e.printStackTrace();
	        }finally {
	            // 所有资源释放完之后，清空资源，再次发起重连操作
	        	executor.execute(new Runnable(){
					public void run() {
						try {
		                    TimeUnit.SECONDS.sleep(5);
		                    //发起重连操作
		                    connect(NettyClient.HOST,NettyClient.PORT);
		                } catch (InterruptedException e) {
		                    e.printStackTrace();
		                }
					}
	        	});
	        	
	           
	        }
	    }
	
	
	  public static void main(String[] args) {
	        new NettyClient().connect(NettyClient.HOST,NettyClient.PORT);
	  }

	
	
	
}
